##############
# (*) Kaleidoscope
# By: Allan Spale
# July 2008

import sys

class KSTransactionError(Exception):
    """
    Exception class for KSTransaction

    """
    B_UNKNOWN_EXCEPTION = True
    B_CLASS_EXCEPTION = False


    def __init__(self, u_message):
        self.__u_message = u_message
    def __str__(self):
        return repr(self.__u_message)

    @staticmethod
    def print_and_raise_error(u_message, b_unknown_exception):
        """
        Convenience method for printing and raising an error for this
        particular Exception subclass.

        """
        u_message = u'KSTransaction.py: ' + u_message
        sys.stderr.write(u_message + u'\n')

        if (b_unknown_exception):
            raise Exception(u_message)
        else:
            raise KSTransactionError(u_message)


class KSTransaction(object):
    """
    Generic transaction object generated by KSTransactionFactory.

    """
    I_STATUS_PENDING = 1
    I_STATUS_COMMIT = 2
    I_STATUS_CANCEL = 3
    I_STATUS_ERROR = 4


    def __init__(self, obj_transaction, fn_caller):
        """
        Receive the transaction object. Because of repeated calls within a
        class that use the same transaction, it is necessary to capture the
        function address of the function that made the initial call to create
        the transaction object. This object will be unique enough to serve
        as a lock so that the function that created the transaction will be
        the only one to commit the transaction.

        """
        self.obj_transaction = obj_transaction
        self.fn_caller = fn_caller
        self.i_transaction_status = KSTransaction.I_STATUS_PENDING
        #print 'commit key function = ', self.fn_caller


    def commit(self, i_flags, fn_caller):
        """
        Apply the transaction to the affected columns only if the function
        that created the transaction is calling the commit function.

        """
        raise NotImplementedError, \
            u'commit must be implemented in a subclass.'


    def cancel(self):
        """
        Discard the transaction on the affected columns.

        """
        raise NotImplementedError, \
            u'cancel must be implemented in a subclass.'


    def get_id(self):
        """
        Obtain the transaction ID.

        """
        raise NotImplementedError, \
            u'get_id must be implemented in a subclass.'